home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 November
/
Macworld (1999-11).dmg
/
Updaters
/
WhiteCap 3.0.4
/
WhiteCap Source.sit
/
WhiteCap Source
/
Common
/
Graphics
/
LineXX.cpp
< prev
next >
Wrap
Text File
|
1999-07-31
|
5KB
|
241 lines
#if CLR_INTERP
void PixPort::_Line( int sx, int sy, int ex, int ey, const RGBColor& inS, long dR, long dG, long dB ) {
#else
void PixPort::_Line( int sx, int sy, int ex, int ey, long color ) {
#endif
long xDirection, rowOffset, error_term;
char* basePtr, *center;
long xmov, ymov, dx, dy, t, j, lw;
long penExtents;
#if CLR_INTERP
long color, R, G, B;
R = inS.red;
G = inS.green;
B = inS.blue;
#endif
// Modify the line width so that the actual width matches mLineWidth
lw = mLineWidth;
if ( mLineWidth > 3 ) {
dx = ex - sx; dx = dx * dx;
dy = ey - sy; dy = dy * dy;
if ( dx > 0 && dx >= dy )
lw = 128 + 55 * dy / dx; // 1/cos( atan( x ) ) is about 1+.43*x^2 from 0 to 1 (55 == .43 * 128)
else if ( dy > 0 && dy > dx )
lw = 128 + 55 * dx / dy; // 1/cos( atan( x ) ) is about 1+.43*x^2 from 0 to 1 (55 == .43 * 128)
if ( dx > 0 || dy > 0 )
lw = ( mLineWidth * lw + 64 ) >> 7; // Add in order to round up
}
penExtents = lw >> 1;
// Clipping: Set the pen loc to a point that's in and stop drawing once/if the pen moves out
if ( sx < penExtents || sx >= mX - penExtents || sy < penExtents || sy >= mY - penExtents ) {
t = ex; ex = sx; sx = t;
t = ey; ey = sy; sy = t;
#if CLR_INTERP
R += dR; G += dG; B += dB;
dR = -dR; dG = -dG; dB = -dB;
#endif
}
// Exit if the start pt is out of bounds (wimpy clipping, eh?)
if ( sx < penExtents || sx >= mX - penExtents || sy < penExtents || sy >= mY - penExtents )
return;
// In Win32, everything's upside down
#if EG_WIN
sy = mY - sy;
ey = mY - ey;
#endif
dx = ex - sx;
dy = ey - sy;
#if CLR_INTERP
long len = sqrt( dx * dx + dy * dy ) + 1;
dR /= len;
dG /= len;
dB /= len;
color = __Clr( R, G, B );
#endif
// moving left or right?
xmov = dx;
if ( dx < 0 ) {
xmov = -dx;
if ( sx - xmov < penExtents )
xmov = sx - penExtents;
xDirection = - P_SZ;
dx = -dx; }
else if ( dx > 0 ) {
if ( sx + xmov >= mX - penExtents )
xmov = mX - penExtents - 1 - sx;
xDirection = P_SZ; }
else
xDirection = 0;
// moving up or down?
ymov = dy;
if ( dy < 0 ) {
ymov = -dy;
if ( sy - ymov < penExtents )
ymov = sy - penExtents;
rowOffset = - mBytesPerRow;
dy = -dy; }
else {
if ( sy + ymov >= mY - penExtents )
ymov = mY - penExtents - sy - 1;
rowOffset = mBytesPerRow;
}
basePtr = mBits + sy * mBytesPerRow + sx * P_SZ;
error_term = 0;
long halfW;
if ( lw > 1 ) {
// Make a circle for the pen
long c_x, tw = mLineWidth;
halfW = ( tw ) >> 1;
if ( tw < 12 ) {
char* c_shape;
__circ( tw, c_shape )
for ( j = 0; j < tw; j++ ) {
long tmp = j - halfW;
c_x = c_shape[ j ];
center = basePtr + (j-halfW) * mBytesPerRow;
for ( int k = c_x; k < tw - c_x; k++ ){
((PIXTYPE*) center)[k-halfW] = color;
}
} }
else {
for ( j = 0; j < tw; j++ ) {
long tmp = j - halfW;
c_x = halfW - ( ( long ) sqrt( halfW * halfW - tmp * tmp ) );
center = basePtr + (j-halfW) * mBytesPerRow;
for ( int k = c_x; k < tw - c_x; k++ ){
((PIXTYPE*) center)[k-halfW] = color;
}
}
}
halfW = lw >> 1;
// Draw the line
if ( dx > dy ) {
// Start counting off in x
for ( ; xmov >= 0 && ymov >= 0; xmov-- ) {
#if CLR_INTERP
__calcClr
#endif
// Draw the vertical leading edge of the pen
center = basePtr - halfW * mBytesPerRow;
for ( j = 0; j < lw; j++ ) {
*((PIXTYPE*) center) = color;
center += mBytesPerRow;
}
/*
// Draw the horizontal leading edge of the pen
center = basePtr + halfW * ( rowOffset - P_SZ );
for ( j = 0; j < lw; j++ ) {
*((PIXTYPE*) center) = color;
center += P_SZ;
}*/
basePtr += xDirection;
// Check to see if we need to move the pixelOffset in the y direction.
__doXerr
} }
else {
// Start counting off in y
for ( ; ymov >= 0 && xmov >= 0; ymov-- ) {
#if CLR_INTERP
__calcClr
#endif
/*
// Draw the vertical leading edge of the pen
center = basePtr + xDirection * (halfW) - P_SZ - halfW * mBytesPerRow;
for ( j = 0; j < lw; j++ ) {
*((PIXTYPE*) center) = color;
center += mBytesPerRow;
}*/
// Draw the horizontal leading edge of the pen
center = basePtr - ( halfW ) * P_SZ;
for ( j = 0; j < lw; j++ ) {
*((PIXTYPE*) center) = color;
center += P_SZ;
}
basePtr += rowOffset;
// Check to see if we need to move the pixelOffset in the y direction.
__doYerr
}
}
// If line len is 0, we don't need to draw ending pen circle
/*
if ( lw > 3 ) {
if ( dx != 0 || dy != 0 ) {
}
} */
}
else {
// Draw the (single pixel) line
if ( dx >= dy ) {
// Start counting off in x
for ( ; xmov >= 0 && ymov >= 0; xmov-- ) {
#if CLR_INTERP
__calcClr
#endif
*((PIXTYPE*) basePtr) = color;
basePtr += xDirection;
// Check to see if we need to move the pixelOffset in the y direction.
__doXerr
} }
else {
// Start counting off in y
for ( ; ymov >= 0 && xmov >= 0; ymov-- ) {
#if CLR_INTERP
__calcClr
#endif
*((PIXTYPE*) basePtr) = color;
basePtr += rowOffset;
// Check to see if we need to move the pixelOffset in the y direction.
__doYerr
}
}
}
}